#pragma once

#include "Data/Data.hpp"
#include "Data/Point2DData.hpp"
#include "Common/Savable.hpp"
#include "Observer/Observer.hpp"
//#include <boost/archive/text_iarchive.hpp>

#include <vector>

/** @class CurveData
  * @brief Класс, хранящий данные, представляющие кривую
  */
class CurveData : public Data, public Savable, public Observer
{
private:
    std::vector< Point2DData* > m_points;

public:
    /**
      * Конструктор по-умолчанию
      */
    CurveData();

    /** 
      * Конструктор
      * 
      * @param points Набор точек, из которых состоит кривая
      */
    CurveData(std::vector< Point2DData* > &points);

    /**
      * Загрузка объекта
      *
      * @param in поток, из которого необходимо считать объект
      * @return код ошибки или 0, если всё хорошо
      */
    virtual int load(std::istream& in);

    /**
      * Сохранение объекта
      *
      * @param out поток, в который необходимо сохранить объект
      * @return код ошибки или 0, если всё хорошо
      */
    virtual int save(std::ostream& out) const;

    /** 
      * Добавить точку
      * 
      * @param p Добавляемая точка
      */
    void addPoint(Point2DData *p);

    /**
      * Удалить точку
      *
      * @param p Удаляемая точка
      */
    void removePoint(Point2DData *p);

    /** 
      * Обновить
      */
    virtual void update();

    /**
      * Получить набор точек, из которых состоит кривая
      *
      * @return Набор точек кривой
      */
    const std::vector< Point2DData* >& getPoints() const;

    /** 
      * Деструктор
      */
    virtual ~CurveData();
    
    /**
      * Оператор сложения двух кривых
      *
      * @param p кривая
      */
    CurveData operator +(const CurveData &p) const;

    /**
      * Оператор вычитания двух кривых
      *
      * @param p кривая
      */
    CurveData operator -(const CurveData &p) const;

	  /**
      * Оператор умножения двух кривых
      *
      * @param p кривая
      */
    CurveData operator *(const CurveData &p) const;

	  /**
      * Оператор деления двух кривых
      *
      * @param p кривая
      */
    CurveData operator / (const CurveData &p) const;

	  /**
      * Оператор присваивания
      *
      * @param p кривая
      */
    CurveData operator =(const CurveData &p);

	  /**
      * Оператор унарный минус
      *
      */
    CurveData operator -() const;

	  /**
      * Получить количество точек в кривой
      *
      */
	  const int size() const;

	  /**
      * Операция sign
      *
      */
	  void sign();
      
//     friend class boost::serialization::access;
     
     /**
      * Функция сериализации
      *
      * @param  ar архив
      */
     template<typename Arhive>
     void serialize(Arhive &ar, const unsigned int );
     
     /**
      * Получить значение кривой в заданной точке
      *
	    * @param х абцисса, в которой нужно получить значение
      */
	   const double  curve(const double x) const;

	  /**
      * Оператор прибавления к кривой константы
      *
      * @param c константа
      */
    CurveData operator +(const double &c) const;

	  /**
      * Оператор вычитания из кривой константы
      *
      * @param c константа
      */
    CurveData operator -(const double &c) const;

	  /**
      * Оператор умножения кривой на константу
      *
      * @param c константа
      */
    CurveData operator *(const double &c) const;

	  /**
      * Оператор деления кривой на константу
      *
      * @param c константа
      */
    CurveData operator /(const double &c) const;
};

